package com.uziot.bucket.tasklock.service.impl;

import com.uziot.bucket.tasklock.dao.TaskLock;
import com.uziot.bucket.tasklock.dao.TaskLockMapper;
import com.uziot.bucket.tasklock.dao.TaskLog;
import com.uziot.bucket.tasklock.dao.TaskLogMapper;
import com.uziot.bucket.tasklock.service.TaskLockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.UUID;

/**
 * @author shidt
 * @version V1.0
 * @className TaskLockServiceImpl
 * @date 2020-12-05 16:25:41
 * @description
 */
@Slf4j
@Service
public class TaskLockServiceImpl implements TaskLockService {

    @Autowired
    private TaskLockMapper taskLockMapper;

    @Autowired
    private TaskLogMapper taskLogMapper;

    /**
     * 创建锁对象
     *
     * @param name 方法名
     * @return 锁对象
     */

    @Override
    public TaskLock createTaskLock(String name) {
        TaskLock taskLock = new TaskLock();
        taskLock.setId(UUID.randomUUID().toString());
        taskLock.setName(name);
        taskLock.setCreateTime(new Timestamp(System.currentTimeMillis()));
        HostInfo localHostInfo = this.getLocalHostInfo();
        taskLock.setHostName(localHostInfo.getHostName());
        taskLock.setHostIp(localHostInfo.getHostIp());
        return taskLock;
    }

    /**
     * 创建定时任务日志对象
     *
     * @param name 方法名称
     * @return 日志对象
     */
    @Override
    public TaskLog createTaskLog(String name) {
        TaskLog taskLog = new TaskLog();
        taskLog.setName(name);
        taskLog.setId(UUID.randomUUID().toString());
        taskLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
        HostInfo localHostInfo = this.getLocalHostInfo();
        taskLog.setHostName(localHostInfo.getHostName());
        taskLog.setHostIp(localHostInfo.getHostIp());
        return taskLog;
    }

    /**
     * 修改定时任务日志
     *
     * @param taskLog taskLog
     */
    @Override
    public void updateTaskLog(TaskLog taskLog) {
        taskLog.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        taskLogMapper.updateTaskLog(taskLog);
    }

    /**
     * 尝试获取锁
     *
     * @param taskLock 锁对象
     * @return boolean
     */
    @Override
    public boolean tryLock(TaskLock taskLock) {
        try {
            taskLockMapper.saveTaskLock(taskLock);
            log.info("抢占锁获取成功！");
            return true;
        } catch (Exception e) {
            log.error("抢占锁获取失败！");
            return false;
        }
    }

    @Override
    public void removeTaskLock(String id) {
        taskLockMapper.removeTaskLock(id);
    }

    @Override
    public void releaseThisHostLock() {
        try {
            String hostName = InetAddress.getLocalHost().getHostName();
            TaskLock taskLock = new TaskLock();
            taskLock.setHostName(hostName);
            taskLockMapper.removeTaskLockByHostName(taskLock);
            log.info("释放本机抢占锁成功！");
        } catch (Exception e) {
            log.error("释放本机抢占锁发生异常：{}", e.toString());
        }

    }

    @Override
    public void saveTaskLog(TaskLog taskLog) {
        taskLogMapper.saveTaskLog(taskLog);
    }


    /**
     * 获取主机信息
     *
     * @return 主机信息
     */
    public HostInfo getLocalHostInfo() {
        String hostName = "ERROR";
        String hostIp = "0.0.0.0";
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            hostName = localHost.getHostName();
            hostIp = localHost.getHostAddress();
        } catch (UnknownHostException e) {
            log.error("获取本地主机信息发生异常！");
        }
        return new HostInfo(hostName, hostIp);
    }


    /**
     * 主机实例信息封装
     */
    private static class HostInfo {
        private String hostName;
        private String hostIp;

        public HostInfo(String hostName, String hostIp) {
            this.hostName = hostName;
            this.hostIp = hostIp;
        }

        public String getHostName() {
            return hostName;
        }

        public void setHostName(String hostName) {
            this.hostName = hostName;
        }

        public String getHostIp() {
            return hostIp;
        }

        public void setHostIp(String hostIp) {
            this.hostIp = hostIp;
        }

        @Override
        public String toString() {
            return "HostInfo{" + "hostName='" + hostName + '\'' +
                    ", hostIp='" + hostIp + '\'' +
                    '}';
        }
    }
}
